'    Copyright 2008 Jan Molnar <jan.molnar@abds.de>
'
'    This file is part of JCQ.

'    JCQ is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 2 of the License, or
'    (at your option) any later version.

'    JCQ is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.

'    You should have received a copy of the GNU General Public License
'    along with JCQ. If not, see <http://www.gnu.org/licenses/>.

Public Class IcqSearchService
    Inherits ContextService
    Implements Interfaces.ISearchService


    ' When a user search is initiated the icq server sends the search results one by one as Snac1503.
    ' The results need to be saved until the last one is received.
    Private ReadOnly _TempFoundUsers As New List(Of Interfaces.IContact)

    Public Sub New(ByVal context As Interfaces.IContext)
        MyBase.New(context)

        Dim connector As IcqConnector = TryCast(context.GetService(Of Interfaces.IConnector)(), IcqConnector)

        If connector Is Nothing Then Throw New InvalidCastException("Context Connector Service must be of Type IcqConnector")

        connector.RegisterSnacHandler(Of DataTypes.Snac1503)(&H15, &H3, New Action(Of DataTypes.Snac1503)(AddressOf AnalyseSnac1503))
    End Sub

    Public Sub SearchByUin(ByVal uin As String) Implements Interfaces.ISearchService.SearchByUin
        Dim dataOut As DataTypes.Snac1502
        dataOut = New DataTypes.Snac1502

        Dim req As DataTypes.MetaSearchByTlvRequest
        req = New DataTypes.MetaSearchByTlvRequest(DataTypes.MetaRequestSubType.SearchByUinRequestTlv)
        req.RequestSequenceNumber = DataTypes.MetaRequest.GetNextSequenceNumber
        req.ClientUin = CLng(Context.Identity.Identifier)

        Dim tlv As DataTypes.SearchByUinTlv
        tlv = New DataTypes.SearchByUinTlv
        tlv.Uin = CInt(uin)

        req.SearchTlvs.Add(tlv)

        dataOut.MetaData.MetaRequest = req

        Dim transfer As IIcqDataTranferService = DirectCast(Context.GetService(Of Interfaces.IConnector)(), IIcqDataTranferService)
        transfer.Send(dataOut)
    End Sub

    Private Sub AnalyseSnac1503(ByVal dataIn As DataTypes.Snac1503)
        Dim info As DataTypes.MetaInformationResponse
        Dim resp As DataTypes.MetaSearchByUinResponse

        Try
            Select Case dataIn.MetaData.MetaResponse.ResponseType
                Case DataTypes.MetaResponseType.MetaInformationResponse
                    info = DirectCast(dataIn.MetaData.MetaResponse, DataTypes.MetaInformationResponse)

                    If info.ResponseSubType = DataTypes.MetaResponseSubType.SearchUserFoundReply Or info.ResponseSubType = DataTypes.MetaResponseSubType.SearchLastUserFoundReply Then
                        resp = DirectCast(dataIn.MetaData.MetaResponse, DataTypes.MetaSearchByUinResponse)

                        Dim contact As Interfaces.IContact

                        contact = Context.GetService(Of Interfaces.IStorageService).GetContactByIdentifier(CStr(resp.FoundUserUin))

                        contact.Name = resp.Nickname
                        contact.FirstName = resp.FirstName
                        contact.LastName = resp.LastName
                        contact.EmailAddress = resp.EmailAddress
                        contact.Gender = DirectCast(resp.Gender, Interfaces.ContactGender)
                        contact.AuthorizationRequired = resp.AutorizationRequired

                        _TempFoundUsers.Add(contact)

                        If info.ResponseSubType = DataTypes.MetaResponseSubType.SearchLastUserFoundReply Then
                            Dim temp As List(Of Interfaces.IContact) = New List(Of Interfaces.IContact)(_TempFoundUsers)
                            _TempFoundUsers.Clear()

                            RaiseEvent SearchResult(Me, New Interfaces.SearchResultEventArgs(temp))
                        End If
                    End If
            End Select
        Catch ex As Exception
            Core.Kernel.Exceptions.PublishException(ex)
        End Try
    End Sub

    Public Event SearchResult(ByVal sender As Object, ByVal e As Interfaces.SearchResultEventArgs) Implements Interfaces.ISearchService.SearchResult
End Class
